﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QIcon>
#include <QMenuBar>
#include <QAction>
#include <QPushButton>
#include <QWidget>
#include <QObject>
#include <QPainter>
#include <QMouseEvent>
#include <QVector>
#include <QRect>
#include <QDebug>
#include <QtMath>

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
    ui->setupUi(this);
    resize(680, 480);
    this->setWindowTitle(u8"画图板");
    QIcon icon(":/new/pictures/windowlogo.jpg");
    this->setWindowIcon(icon);


    pix = new QPixmap(size());
    pix->fill(Qt::white);
    save = false;
    m_pressFlag=false;
    QMenuBar *bar = menuBar();
    this->setMenuBar(bar);
    width=1;
    color.setRgb(0,0,0);//黑色
    style=Qt::PenStyle(1);//初始化

    QMenu *DocMenu = bar->addMenu(u8"文件");
    QMenu *EditMenu = bar->addMenu(u8"编辑");
    QMenu *MoveMenu = bar->addMenu(u8"移动");
    QMenu *PaintMenu = bar->addMenu(u8"绘图");
    QMenu *WidthMenu = bar->addMenu(u8"粗细");
    QMenu *StyleMenu = bar->addMenu(u8"样式");

    MoveMenu->setTearOffEnabled(true);

    QAction *save = new QAction(tr(u8"保存"),this);
    DocMenu->addAction(save);
    QAction *open = new QAction(tr(u8"打开"),this);
    DocMenu->addAction(open);

    QAction *large = new QAction(u8"&放大", this);
    EditMenu->addAction(large);
    QAction *small = new QAction(tr(u8"缩小"), this);
    EditMenu->addAction(small);
    QAction *copyOne = new QAction(u8"复制", this);
    EditMenu->addAction(copyOne);
    QAction *clear = new QAction(tr(u8"清除"), this);
    EditMenu->addAction(clear);

    QAction *leftMove = new QAction(u8"左移",this);
    MoveMenu->addAction(leftMove);
    QAction *rightMove = new QAction(u8"右移",this);
    MoveMenu->addAction(rightMove);
    QAction *upMove = new QAction(u8"上移",this);
    MoveMenu->addAction(upMove);
    QAction *downMove = new QAction(u8"下移",this);
    MoveMenu->addAction(downMove);

    QAction *CurveAction = new QAction(tr(u8"曲线"), this);
    PaintMenu->addAction(CurveAction);
    QAction *LineAction = new QAction(tr(u8"直线"), this);
    PaintMenu->addAction(LineAction);
    QAction *RectAction = new QAction(tr(u8"矩形"), this);
    PaintMenu->addAction(RectAction);
    QAction *CircleAction = new QAction(tr(u8"圆"), this);
    PaintMenu->addAction(CircleAction);
    QAction *EllipseAction = new QAction(tr(u8"椭圆"), this);
    PaintMenu->addAction(EllipseAction);

    QAction *ColorAction = new QAction(tr("颜色"),this);
    bar->addAction(ColorAction);
    QAction *AAction = new QAction(tr("细"),this);
    WidthMenu->addAction(AAction);
    QAction *BAction = new QAction(tr("中"),this);
     WidthMenu->addAction(BAction);
    QAction *CAction = new QAction(tr("粗"),this);
    WidthMenu->addAction(CAction);
    QAction *DAction = new QAction(tr("实线"),this);
    StyleMenu->addAction(DAction);
    QAction *EAction = new QAction(tr("虚线"),this);
    StyleMenu->addAction(EAction);
    QAction *FAction = new QAction(tr("点线"),this);
    StyleMenu->addAction(FAction);

    connect(LineAction, SIGNAL(triggered(bool)), this, SLOT(Line()));
    connect(RectAction, SIGNAL(triggered(bool)), this, SLOT(Rect()));
    connect(CircleAction, SIGNAL(triggered(bool)), this, SLOT(Circle()));
    connect(EllipseAction, SIGNAL(triggered(bool)), this, SLOT(Ellipse()));
    connect(clear, SIGNAL(triggered(bool)), this, SLOT(ClearPainter()));
    connect(large, SIGNAL(triggered(bool)),this, SLOT(Large()));
    connect(small, SIGNAL(triggered(bool)),this, SLOT(Small()));
    connect(leftMove, SIGNAL(triggered(bool)), this, SLOT(Left()));
    connect(rightMove, SIGNAL(triggered(bool)), this, SLOT(Right()));
    connect(upMove, SIGNAL(triggered(bool)), this, SLOT(Up()));
    connect(downMove, SIGNAL(triggered(bool)), this, SLOT(Down()));
    connect(save, SIGNAL(triggered(bool)),this, SLOT(SavePic()));
    connect(open, SIGNAL(triggered(bool)),this, SLOT(OpenPic()));
    connect(copyOne, SIGNAL(triggered(bool)), this, SLOT(Copy()));
    connect(CurveAction,SIGNAL(triggered(bool)),this, SLOT(Curve()));
    connect(ColorAction,SIGNAL(triggered(bool)),this,SLOT(SetColor()));
    connect(AAction,SIGNAL(triggered(bool)),this,SLOT(SetWidth3()));
    connect(BAction,SIGNAL(triggered(bool)),this,SLOT(SetWidth2()));
    connect(CAction,SIGNAL(triggered(bool)),this,SLOT(SetWidth1()));
    connect(DAction,SIGNAL(triggered(bool)),this,SLOT(SetStyle1()));
    connect(EAction,SIGNAL(triggered(bool)),this,SLOT(SetStyle2()));
    connect(FAction,SIGNAL(triggered(bool)),this,SLOT(SetStyle3()));
}

bool MainWindow::saveDrawingToFile(const QString &fileName) {
    QJsonObject json;
    QJsonArray shapesArray;

    // 将绘图内容序列化到JSON数组中
    int i = 0;
    for (const Shape &shape : shapes) {
        if(i >= shapes.count()){
            break;
        }
        QJsonObject shapeObject;
        shapeObject["type"] = shape.type;
        QJsonObject rectObject;
        rectObject["x"] = shape.rect.x();
        rectObject["y"] = shape.rect.y();
        rectObject["width"] = shape.rect.width();
        rectObject["height"] = shape.rect.height();

        shapeObject["rect"] = rectObject; // 将矩形对象添加到 shapeObject 中
        shapeObject["lineColor"] = shape.lineColor.name();
        shapeObject["color"] =  m_colors.at(i).name();
        shapeObject["width"] =  m_widths.at(i);
        shapeObject["style"] =  m_penStyles.at(i);
        qDebug() << m_colors.at(i).name() << m_widths.at(i) << m_penStyles.at(i);
        shapesArray.append(shapeObject);
        ++i;
    }

    json["shapes"] = shapesArray;

    // 将JSON对象写入文件
    QFile file(fileName);
    if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QTextStream out(&file);
        out << QJsonDocument(json).toJson();
        file.close();
        return true;
    }
    return false;
}

bool MainWindow::loadDrawingFromFile(const QString &fileName) {
    QFile file(fileName);
    if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QByteArray data = file.readAll();
        file.close();

        QJsonDocument jsonDoc = QJsonDocument::fromJson(data);
        QJsonObject jsonObj = jsonDoc.object();

        // 清空当前的绘图内容
        shapes.clear();
        m_colors.clear();
        m_widths.clear();
        m_penStyles.clear();

        // 从JSON数据中加载绘图内容
        if (jsonObj.contains("shapes") && jsonObj["shapes"].isArray()) {
            QJsonArray shapesArray = jsonObj["shapes"].toArray();
            for (const QJsonValue &shapeValue : shapesArray) {
                QJsonObject shapeObj = shapeValue.toObject();
                Shape::Type type = static_cast<Shape::Type>(shapeObj["type"].toInt());
                QJsonValue rectValue = shapeObj["rect"];
                QRect rect;
                if (rectValue.isObject()) {
                    QJsonObject rectObj = rectValue.toObject();
                    int x = rectObj["x"].toInt();
                    int y = rectObj["y"].toInt();
                    int width = rectObj["width"].toInt();
                    int height = rectObj["height"].toInt();
                    rect = QRect(x, y, width, height);
                } else {
                    // 处理无效的矩形数据，例如，如果 "rect" 不是一个对象。
                }


                QColor lineColor(shapeObj["lineColor"].toString());
                m_colors.append(shapeObj["color"].toString());
                m_widths.append(shapeObj["width"].toInt());
                m_penStyles.append(Qt::PenStyle(shapeObj["style"].toInt()));
                shapes.append(Shape(type, rect, lineColor));
            }
        }

        // 更新视图
        update();

        return true;
    }

    return false;
}

void MainWindow::mousePressEvent(QMouseEvent *event) {
    start = event->pos();
    selectedShape = nullptr; // 清除当前选中的图形
    save = true;
    m_pressFlag=true;

    // 检查鼠标点击是否在图形内部
    for (Shape &shape : shapes) {
        if (shape.rect.contains(start)) {
            shape.isSelected = true;
        } else {
            shape.isSelected = false;
        }
    }
    update();
}

void MainWindow::mouseReleaseEvent(QMouseEvent *event) {
    end = event->pos();
     m_pressFlag=false;
    if (save) {
        m_colors.append(color);
        m_widths.append(width);
        m_penStyles.append(style);
        if (selectedShapeType == Shape::Line) {
            shapes.append(Shape(Shape::Line, QRect(start, end), selectedLineColor));
        } else if (selectedShapeType == Shape::Rectangle) {
            shapes.append(Shape(Shape::Rectangle, QRect(start, end), selectedLineColor));
        } else if (selectedShapeType == Shape::Circle) {
            int r = qSqrt(qPow(end.x() - start.x(), 2) + qPow(end.y() - start.y(), 2));
           shapes.append(Shape(Shape::Circle, QRect(start.x() - r, start.y() - r, 2 * r, 2 * r), selectedLineColor));
        } else if (selectedShapeType == Shape::Ellipse) {
            shapes.append(Shape(Shape::Ellipse, QRect(start, end), selectedLineColor));
        }
        update();
    }
    save = false;
}

void MainWindow::mouseMoveEvent(QMouseEvent *event) {
    end = event->pos();
    if(m_pressFlag)
    {
        QPoint pos=event->pos();
        m_points.append(pos);
        //qDebug("(%d,%d)",pos.x(),pos.y());



        update();
    }
    update();
}

void MainWindow::paintEvent(QPaintEvent *event) {
    QPainter p(pix);
    QPen pen;
    //pen.setColor(color);
    p.setPen(color);
    pen.setWidth(width);
    pen.setStyle(style);

    int i = 0;
    for (const Shape &shape : shapes)
    {
        if(i < shapes.count()){

        //p.setPen(QPen(shape.lineColor));
        if(shape.isSelected)/*{p.setPen(QPen(Qt::red, 3));}*/{p.setPen(color);}
        if(!shape.isSelected){
                pen.setWidth(m_widths.at(i));
                pen.setStyle(m_penStyles.at(i));
                pen.setColor(m_colors.at(i));
                p.setPen(pen);
            }//p.setPen(QPen(Qt::black, 1));}
        if (shape.type == Shape::Line) {
            p.drawLine(shape.rect.topLeft(), shape.rect.bottomRight());
        } else if (shape.type == Shape::Rectangle){
            p.drawRect(shape.rect);
        } else if (shape.type == Shape::Circle) {
            p.drawEllipse(shape.rect);
        } else if (shape.type == Shape::Ellipse) {
            p.drawEllipse(shape.rect);
        }
        else if(shape.type == Shape::Curve)
        {
            if(m_pressFlag)
            {
                for(int i=1;i<m_points.size()-1;i++)
                {
                    QPoint & p1=m_points[i];
                    QPoint & p2=m_points[i+1];
                    if(i==1){p.drawLine(start,p2);}
                    else
                    { p.drawLine(p1,p2);}
                }
            }
        }
        ++i;
        }
    }

    QPainter px(this);
    px.setPen(pen);
    px.drawPixmap(0, 0, *pix);
    if (selectedShapeType == Shape::Line) {
        px.setPen(QPen(selectedLineColor));
        px.drawLine(start, end);
    } else if (selectedShapeType == Shape::Rectangle) {
        px.setPen(QPen(selectedLineColor));
        px.drawRect(QRect(start, end));
    } else if (selectedShapeType == Shape::Circle) {
        int r = qSqrt(qPow(end.x() - start.x(), 2) + qPow(end.y() - start.y(), 2));
        px.setPen(QPen(selectedLineColor));
        px.drawEllipse(QRect(start.x() - r, start.y() - r, 2 * r, 2 * r));
    } else if (selectedShapeType == Shape::Ellipse) {
        px.setPen(QPen(selectedLineColor));
        px.drawEllipse(QRect(start, end));
    }
    else if(selectedShapeType = Shape::Curve)
    {
        {
            for(int i=0;i<m_points.size()-1;i++)
            {
                QPoint & p1=m_points[i];
                QPoint & p2=m_points[i+1];
                px.drawLine(p1,p2);
            }
        }
    }
}




void MainWindow::Line() {
    selectedShapeType = Shape::Line;
}

void MainWindow::Rect() {
    selectedShapeType = Shape::Rectangle;
}

void MainWindow::Circle() {
    selectedShapeType = Shape::Circle;
}

void MainWindow::Ellipse() {
    selectedShapeType = Shape::Ellipse;
}

void MainWindow::Curve()
{
    selectedShapeType = Shape::Curve;
}

void MainWindow::ClearPainter() {
    selectedShapeType = Shape::None;
    pix->fill(Qt::white);
    shapes.clear();
    m_points.clear();

    m_colors.clear();
    m_widths.clear();
    m_penStyles.clear();

    update();
}

void MainWindow::SavePic() {
    QString fileName = QFileDialog::getSaveFileName(this, tr(u8"保存"), "drawing.json", "JSON Files (*.json)");

    if (!fileName.isEmpty()) {
        if (saveDrawingToFile(fileName)) {
            QMessageBox::information(this, tr(u8"保存成功"), tr(u8"图形已成功保存到文件！"));
        } else {
            QMessageBox::critical(this, tr(u8"保存失败"), tr(u8"无法保存图形到文件。"));
        }
    }
}

void MainWindow::OpenPic() {
    QString fileName = QFileDialog::getOpenFileName(this, tr(u8"打开"), "", "JSON Files (*.json)");

    if (!fileName.isEmpty()) {
        if (loadDrawingFromFile(fileName)) {
            QMessageBox::information(this, tr(u8"打开成功"), tr(u8"已成功加载图形文件！"));
        } else {
            QMessageBox::critical(this, tr(u8"打开失败"), tr(u8"无法打开图形文件。"));
        }
    }
}
void MainWindow::Large()
{

    for (Shape &shape : shapes)
    {
        if(shape.isSelected)
        {
            //QPixmap doLarge = QPixmap(shape.rect.width(), shape.rect.height());
            //QPainter dl(&doLarge);
            //m_scaleValue *= 1.1;
            currentWidth = shape.rect.width() *1.05;
            currentHeight = shape.rect.height() *1.05;
            pix->fill();
            //dl.scale(currentWidth,currentHeight);
            shape.rect.setWidth(currentWidth);
            shape.rect.setHeight(currentHeight);
            update();


        }
    }
}
void MainWindow::Small()
{

    for (Shape &shape : shapes)
    {
        if(shape.isSelected)
        {
            //QPixmap doLarge = QPixmap(shape.rect.width(), shape.rect.height());
            //QPainter dl(&doLarge);
            //m_scaleValue *= 1.1;
            currentWidth = shape.rect.width() *0.95;
            currentHeight = shape.rect.height() *0.95;
            pix->fill();
            //dl.scale(currentWidth,currentHeight);
            shape.rect.setWidth(currentWidth);
            shape.rect.setHeight(currentHeight);
            update();


        }
    }
}

void MainWindow::Left()
{
    for(Shape &shape : shapes)
    {
        if(shape.isSelected)
        {
            currentLeft = shape.rect.left()-5;
            currentRight = shape.rect.right()-5;
            pix->fill();
            shape.rect.setLeft(currentLeft);
            shape.rect.setRight(currentRight);
            update();
        }
    }
}
void MainWindow::Right()
{
    for(Shape &shape : shapes)
    {
        if(shape.isSelected)
        {
            currentLeft = shape.rect.left()+5;
            currentRight = shape.rect.right()+5;
            pix->fill();
            shape.rect.setLeft(currentLeft);
            shape.rect.setRight(currentRight);
            update();
        }
    }
}
void MainWindow::Up()
{
    for(Shape &shape : shapes)
    {
        if(shape.isSelected)
        {
            currentTop = shape.rect.top()-5;
            currentBottom = shape.rect.bottom()-5;
            pix->fill();
            shape.rect.setTop(currentTop);
            shape.rect.setBottom(currentBottom);
            update();
        }
    }
}
void MainWindow::Down()
{
    for(Shape &shape : shapes)
    {
        if(shape.isSelected)
        {
            currentTop = shape.rect.top()+5;
            currentBottom = shape.rect.bottom()+5;
            pix->fill();
            shape.rect.setTop(currentTop);
            shape.rect.setBottom(currentBottom);
            update();
        }
    }
}
void MainWindow::Copy()
{
    for(Shape &shape : shapes)
    {
        if(shape.isSelected)
        {
            currentTop = shape.rect.top()+150;
            currentBottom = shape.rect.bottom()+150;
            shape.rect.setTop(currentTop);
            shape.rect.setBottom(currentBottom);

            update();
        }
    }
}


void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Left)
    {
        for(Shape &shape : shapes)
        {
            if(shape.isSelected)
            {
                currentLeft = shape.rect.left()-5;
                currentRight = shape.rect.right()-5;
                pix->fill();
                shape.rect.setLeft(currentLeft);
                shape.rect.setRight(currentRight);
                update();
            }
        }
    }
    else if(event->key() == Qt::Key_Right)
    {
        for(Shape &shape : shapes)
        {
            if(shape.isSelected)
            {
                currentLeft = shape.rect.left()+5;
                currentRight = shape.rect.right()+5;
                pix->fill();
                shape.rect.setLeft(currentLeft);
                shape.rect.setRight(currentRight);
                update();
            }
        }
    }
    else if(event->key() == Qt::Key_Up)
    {
        for(Shape &shape : shapes)
        {
            if(shape.isSelected)
            {
                currentTop = shape.rect.top()-5;
                currentBottom = shape.rect.bottom()-5;
                pix->fill();
                shape.rect.setTop(currentTop);
                shape.rect.setBottom(currentBottom);
                update();
            }
        }
    }
    else if(event->key() == Qt::Key_Down)
    {
        for(Shape &shape : shapes)
        {
            if(shape.isSelected)
            {
                currentTop = shape.rect.top()+5;
                currentBottom = shape.rect.bottom()+5;
                pix->fill();
                shape.rect.setTop(currentTop);
                shape.rect.setBottom(currentBottom);
                update();
            }
        }
    }
}

void MainWindow::wheelEvent(QWheelEvent *event)
{
    if(event->angleDelta().y()>0)
    {
        for (Shape &shape : shapes)
        {
            if(shape.isSelected)
            {
                //QPixmap doLarge = QPixmap(shape.rect.width(), shape.rect.height());
                //QPainter dl(&doLarge);
                //m_scaleValue *= 1.1;
                currentWidth = shape.rect.width() *1.05;
                currentHeight = shape.rect.height() *1.05;
                pix->fill();
                //dl.scale(currentWidth,currentHeight);
                shape.rect.setWidth(currentWidth);
                shape.rect.setHeight(currentHeight);
                update();


            }
        }
    }
    else if(event->angleDelta().y()<0)
    {
        for (Shape &shape : shapes)
        {
            if(shape.isSelected)
            {
                //QPixmap doLarge = QPixmap(shape.rect.width(), shape.rect.height());
                //QPainter dl(&doLarge);
                //m_scaleValue *= 1.1;
                currentWidth = shape.rect.width() *0.95;
                currentHeight = shape.rect.height() *0.95;
                pix->fill();
                //dl.scale(currentWidth,currentHeight);
                shape.rect.setWidth(currentWidth);
                shape.rect.setHeight(currentHeight);
                update();


            }
        }
    }
}
void MainWindow::SetColor()
{
//    for(Shape &shape : shapes)
//    {
//        if(shape.isSelected)
//        {
//            shape.lineColor = QColorDialog::getColor();
//        }
//    }
    color=QColorDialog::getColor();

}
void MainWindow::SetWidth1()
{
    width=10;
}
void MainWindow::SetWidth2()
{
    width=5;
}
void MainWindow::SetWidth3()
{
    width=1;
}
void MainWindow::SetStyle1()
{
     style=Qt::PenStyle(1);
}
void MainWindow::SetStyle2()
{
      style=Qt::PenStyle(2);
}
void MainWindow::SetStyle3()
{
     style=Qt::PenStyle(3);
}


MainWindow::~MainWindow() {
    delete ui;
}
